/*
** label_undefine.c for asm in /home/vanet_c//proj-kw/asm
** 
** Made by charles-edouard vanet
** Login   <vanet_c@epitech.net>
** 
** Started on  Wed Dec 12 20:25:54 2012 charles-edouard vanet
** Last update Sat Dec 15 15:57:58 2012 charles-edouard vanet
*/

#include	"../../includes/asm.h"

void	check_label_name(t_list **file_list, t_my_file **my_file, char *my_label)
{
  int	i;
  int	l;
  int	is_ok;

  i = 0;
  while (my_label[++i] != '\0' && my_label[i] != ':')
    {
      l = -1;
      is_ok = 1;
      while (LABEL_CHARS[++l])
	if (my_label[i] != LABEL_CHARS[l])
	  is_ok++;
      if (is_ok != l)
	{
	  my_fd_putchar('\t', 2);
	  my_stderror((*file_list)->name);
	  my_stderror(": forbidden character used in label \"");
	  my_stderror(my_label);
	  my_stderror("\" line ");
	  my_put_nbr_error((*my_file)->line_nb);
	  my_stderror("\n\e[1mAssembling aborted on error.\e[0m\n");
	  my_free_list(*file_list);
	  exit(EXIT_FAILURE);
	}
    }
}

void	label_undefine_error(t_list **file_list, t_my_file **my_file, char *label)
{
  my_fd_putchar('\t', 2);
  my_stderror((*file_list)->name);
  my_stderror(": label \"");
  my_stderror(label);
  my_stderror("\" undefine line ");
  my_put_nbr_error((*my_file)->line_nb);
  my_stderror("\n\e[1mAssembling aborted on error.\e[0m\n");
  my_free_list(*file_list);
  exit(EXIT_FAILURE);
}

void	creating_label_ok(t_list **file_list, t_my_file **my_file, char **tab, int tab_pos)
{
  if (tab_pos != 0)
    label_undefine_error(file_list, my_file, tab[tab_pos]);
  check_label_name(file_list, my_file, tab[tab_pos]);
  if (tab[1] == NULL)
    label_undefine_error(file_list, my_file, tab[tab_pos]);
}

void		using_label_ok(t_list **file_list, t_my_file **my_file, char *label)
{
  char		*new_label;
  t_my_file	*tmp_file;
  int		is_ok;
  int		i;

  i = 2;
  is_ok = 0;
  new_label = malloc(my_strlen(label));
  while (label[i] != '\0')
    new_label[i - 2] = label[i++];
  new_label[i - 2] = LABEL_CHAR;
  new_label[i - 1] = '\0';
  tmp_file = (*file_list)->file;
  while (tmp_file != NULL)
    {
      i = -1;
      while (tmp_file->tab_instruction[++i] != NULL)
	if ((my_strcmp(new_label, tmp_file->tab_instruction[i]) == 0))
	  is_ok += 1;
      tmp_file = tmp_file->next;
    }
  free(new_label);
  if (is_ok != 1)
    label_undefine_error(file_list, my_file, label + 2);
}

int	label_undefine(t_list **file_list, t_my_file **my_file)
{
  int	t;
  int	c;

  t = -1;
  while ((*my_file)->tab_instruction[++t] != NULL)
    {
      c = 0;
      if ((*my_file)->tab_instruction[t][0] != '\0' &&
	  (*my_file)->tab_instruction[t][1] == LABEL_CHAR)
	using_label_ok(file_list, my_file, (*my_file)->tab_instruction[t]);
      else
	{
	  c = my_strlen((*my_file)->tab_instruction[t]) - 1;
	  if ((*my_file)->tab_instruction[t][0] != '\0' &&
	      (*my_file)->tab_instruction[t][c] == LABEL_CHAR)
	    creating_label_ok(file_list, my_file, (*my_file)->tab_instruction, t);
	}
    }
  return (0);
}
